package org.dromara.easyes.solon.integration;

import org.dromara.easyes.annotation.Intercepts;
import org.dromara.easyes.core.kernel.BaseEsMapper;
import org.dromara.easyes.extension.context.Interceptor;
import org.dromara.easyes.extension.context.InterceptorChainHolder;
import org.dromara.easyes.solon.config.DynamicEsProperties;
import org.dromara.easyes.solon.config.EasyEsConfigProperties;
import org.dromara.easyes.solon.config.EsAutoConfiguration;
import org.dromara.easyes.solon.service.AutoProcessIndexService;
import org.dromara.easyes.solon.service.impl.AutoProcessIndexNotSmoothlyServiceImpl;
import org.dromara.easyes.solon.service.impl.AutoProcessIndexSmoothlyServiceImpl;
import org.elasticsearch.client.RestHighLevelClient;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.AppContext;
import org.noear.solon.core.Plugin;
import org.noear.solon.core.util.ClassUtil;

/**
 * @author noear 2024/10/23 created
 */
public class EasyEsPlugin implements Plugin {
    @Override
    public void start(AppContext context) throws Throwable {
        if (ClassUtil.hasClass(() -> RestHighLevelClient.class) == false) {
            return;
        }

        if (context.cfg().getBool("easy-es.enable", true) == false) {
            return;
        }

        if (context.cfg().containsKey("easy-es.address") == false) {
            return;
        }

        context.beanMake(DynamicEsProperties.class);
        context.beanMake(EasyEsConfigProperties.class);
        context.beanMake(EsAutoConfiguration.class);

        context.beanMake(AutoProcessIndexNotSmoothlyServiceImpl.class);
        context.beanMake(AutoProcessIndexSmoothlyServiceImpl.class);

        EasyEsMapperFactory mapperFactory = context.beanMake(EasyEsMapperFactory.class).get();

        //注册 Intercepts 处理
        context.beanBuilderAdd(Intercepts.class, (clz, bw, anno) -> {
            context.wrapPublish(bw);
        });

        //订阅
        context.subBeansOfType(Interceptor.class, bean -> {
            InterceptorChainHolder.getInstance().initInterceptorChain();
            InterceptorChainHolder.getInstance().addInterceptor(bean);
        });

        context.subBeansOfType(AutoProcessIndexService.class, bean -> {
            mapperFactory.addStrategy(bean);
        });

        //添加 BaseEsMapper 注入支持
        context.beanInjectorAdd(Inject.class, BaseEsMapper.class, (vh, anno) -> {
            //设为必须
            vh.required(anno.required());

            //获取 bean
            Object bean = vh.context().getBean(vh.getType());
            if (bean == null) {
                bean = mapperFactory.getObject(vh.getType());
                vh.context().wrapAndPut(bean.getClass(), bean);
                vh.context().wrapAndPut(vh.getType(), bean);
            }

            //设值
            vh.setValue(bean);
        });
    }
}
